package com.ruoyi.common.utils;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

/**
 * json工具类
 * @author chenzf
 * @date 2016年9月11日
 */
public class JsonUtils {
    private static final GsonBuilder GSON_BUILDER = new GsonBuilder();

    /**
     * 创建基本gson
     * @param names 过滤的字段名
     * @return  gson对象
     */
    public static Gson createGson(final String... names) {
        ExclusionStrategy exclusionStrategy = new ExclusionStrategy() {

            @Override
            public boolean shouldSkipField(FieldAttributes fa) {
                if (ArrayUtils.isEmpty(names)) {
                    return false;
                }
                for (String name : names) {
                    if (fa.getName().equals(name)) {
                        return true;
                    }
                }
                return false;
            }

            @Override
            public boolean shouldSkipClass(Class<?> arg0) {
                return false;
            }
        };
        return build("yyyy-MM-dd HH:mm:ss", exclusionStrategy)
                .create();
    }

    /**
     * 将json数据转化成map对象
     * @param json json字符串
     * @return Map<String, String>
     */
    public static Map<String, String> toMap(String json) {
        return createGson().fromJson(json, new TypeToken<Map<String, String>>() {
        }.getType());
    }

    /**
     * 将对象转换成json字符串
     * @param object
     * @return
     */
    public static String toJson(Object object) {
        return createGson().toJson(object);
    }

    /**
     * 将对象转换成json格式map
     * @param object
     * @return
     */
    public static Map<String, String> toJsonMap(Object object) {
        return toMap(toJson(object));
    }

    /**
     * 格式化字段名成json数据 <br>
     * someFieldName ---> some_field_name
     * @param object
     * @return
     */
    public static String formatFiledName(Object object) {
        return build(true).create().toJson(object);
    }

    /**
     * 格式化字段名并转换成对象<br>
     * someFieldName ---> some_field_name
     * @param json
     * @param clazz
     * @return
     */
    public static <T> T parseFiledName(String json, Class<T> clazz) throws Exception {
        T newInstance = clazz.newInstance();
        Gson gson = build(true).create();
        if (newInstance instanceof List || newInstance instanceof Map) {
            return gson.fromJson(json, new TypeToken<T>() {
            }.getType());
        }
        return gson.fromJson(json, clazz);
    }

    /**
     * 格式化Map字段名并转换成对象<br>
     * some_field_name ---> someFieldName
     * @param map
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T, K, V> T parseFiledName(Map<K, V> map, Class<T> clazz) throws Exception {
        return parseFiledName(toJson(map), clazz);
    }

    /**
     * 将对象的字段名格式化并转换成map
     * @param object
     * @return
     */
    public static Map<String, String> formatFiledtoMap(Object object) {
        return toMap(formatFiledName(object));
    }

    private static GsonBuilder build(boolean isFormat) {
        return build(isFormat, null);
    }

    private static GsonBuilder build(String dateFormat, ExclusionStrategy... exclusionStrategy) {
        return build(false, dateFormat, exclusionStrategy);
    }

    private static GsonBuilder build(boolean isFormat, String dateFormat, ExclusionStrategy... exclusionStrategy) {
        return build(isFormat, true, dateFormat, exclusionStrategy);
    }

    private static GsonBuilder build(boolean isFormat, boolean isLongToString, String dateFormat,
                                     ExclusionStrategy... exclusionStrategy) {
        if (isFormat) {
            GSON_BUILDER.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        }
        if (isLongToString) {
            GSON_BUILDER.setLongSerializationPolicy(LongSerializationPolicy.STRING);
        }
        if (StringUtils.isNotBlank(dateFormat)) {
            GSON_BUILDER.setDateFormat(dateFormat);
        }
        if (exclusionStrategy != null) {
            GSON_BUILDER.setExclusionStrategies(exclusionStrategy);
        }

        return GSON_BUILDER
                //配合@Expose注解
                //serialize：是否序列化该字段，默认true
                //deserialize：是否反序列化该字段，默认true
                .excludeFieldsWithoutExposeAnnotation()
                //配合@Since注解使用，1.0版本后的被过滤
                //.setVersion(1.0)
                //.serializeNulls()//序列化过称中过滤null的字段
                ;
    }
}